package org.jetlinks.pro.assets.crud;

import org.hswebframework.ezorm.rdb.mapping.defaults.SaveResult;
import org.hswebframework.web.authorization.exception.AccessDenyException;
import org.hswebframework.web.crud.web.reactive.ReactiveServiceCrudController;
import org.hswebframework.web.exception.NotFoundException;
import org.jetlinks.pro.assets.AssetsHolder;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

/**
 * 支持关联资产数据权限控制到通用增删改查控制器
 *
 * @param <E> 实体类型
 * @param <K> 主键类型
 * @author zhouhao
 * @since 1.11
 */
public interface CorrelatesAssetsHolderCrudController<E, K> extends CorrelatesAssetsHolderQueryController<E, K>,
    ReactiveServiceCrudController<E, K>,
    CorrelatesAssetsHolderSupport<E> {

    @Override
    default Mono<SaveResult> save(@RequestBody Flux<E> payload) {
        return ReactiveServiceCrudController
            .super
            .save(AssetsHolder.assertPermission(payload, getAssetType(), getAssetIdMapper(), true, CrudAssetPermission.save));
    }

    @Override
    @PutMapping("/{id}")
    default Mono<Boolean> update(@PathVariable K id, @RequestBody Mono<E> payload) {
        return this
            .assertPermission(getService()
                                  .findById(id)
                                  .switchIfEmpty(Mono.error(NotFoundException::new)), CrudAssetPermission.save)
            .flatMap(old -> ReactiveServiceCrudController.super.update(id, payload));
    }

    @Override
    default Mono<E> add(@RequestBody Mono<E> payload) {
        return ReactiveServiceCrudController.super.add(assertPermission(payload));
    }

    @Override
    default Mono<Integer> add(@RequestBody Flux<E> payload) {
        return ReactiveServiceCrudController.super.add(assertPermission(payload));
    }

    @Override
    @DeleteMapping("/{id:.+}")
    default Mono<E> delete(@PathVariable K id) {
        return this
            .assertPermission(getService().findById(id), CrudAssetPermission.delete)
            .flatMap(old -> ReactiveServiceCrudController.super.delete(id));
    }

}
